package service

import (
	"context"
	"errors"
	"fmt"
	"time"

	"gitee.com/daonna/collab-manage-system/ent"
	"gitee.com/daonna/collab-manage-system/ent/conversation"
	"gitee.com/daonna/collab-manage-system/ent/conversationmember"
	"gitee.com/daonna/collab-manage-system/ent/user"
	"gitee.com/daonna/collab-manage-system/repository/db"
)

// MemberInfo 成员信息结构体
type MemberInfo struct {
	ID          int64     `json:"id"`
	UserID      int64     `json:"user_id"`
	Username    string    `json:"username"`
	DisplayName string    `json:"display_name"`
	AvatarURL   string    `json:"avatar_url"`
	Role        string    `json:"role"`
	JoinedAt    time.Time `json:"joined_at"`
}

// GetGroupMembers 获取群组成员列表
func GetGroupMembers(ctx context.Context, groupID int64) ([]MemberInfo, error) {
	client := db.GetDBClient()

	// 检查会话是否存在且是群聊
	_, err := client.Conversation().Conversation.
		Query().
		Where(
			conversation.ID(groupID),
			conversation.TypeEQ(conversation.TypeGroup),
		).
		Only(ctx)

	if err != nil {
		if ent.IsNotFound(err) {
			return nil, errors.New("群组不存在")
		}
		return nil, fmt.Errorf("查询群组失败: %w", err)
	}

	// 查询群组成员
	members, err := client.ConversationMember().ConversationMember.
		Query().
		Where(
			conversationmember.ConversationID(groupID),
		).
		WithUser().
		All(ctx)

	if err != nil {
		return nil, fmt.Errorf("查询群组成员失败: %w", err)
	}

	// 构建返回结果
	result := make([]MemberInfo, 0, len(members))
	for _, member := range members {
		u := member.Edges.User
		if u == nil {
			continue // 跳过没有关联用户的成员
		}

		result = append(result, MemberInfo{
			ID:          member.ID,
			UserID:      u.ID,
			Username:    u.Username,
			DisplayName: u.DisplayName,
			AvatarURL:   u.AvatarURL,
			Role:        member.Role.String(),
			JoinedAt:    member.JoinedAt,
		})
	}

	return result, nil
}

// AddGroupMember 添加群组成员
func AddGroupMember(ctx context.Context, groupID, operatorID, userID uint, role string) error {
	client := db.GetDBClient()

	// 开始事务
	tx, err := client.Group().Tx(ctx)
	if err != nil {
		return fmt.Errorf("开始事务失败: %w", err)
	}
	defer func() {
		if v := recover(); v != nil {
			tx.Rollback()
			panic(v)
		}
	}()

	// 检查会话是否存在且是群聊
	_, err = client.Conversation().Conversation.
		Query().
		Where(
			conversation.ID(int64(groupID)),
			conversation.TypeEQ(conversation.TypeGroup),
		).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("群组不存在")
		}
		return fmt.Errorf("查询群组失败: %w", err)
	}

	// 检查操作者是否有权限（群主或管理员）
	operatorMember, err := client.ConversationMember().ConversationMember.
		Query().
		Where(
			conversationmember.ConversationID(int64(groupID)),
			conversationmember.UserID(int64(operatorID)),
			conversationmember.RoleIn(conversationmember.RoleOwner, conversationmember.RoleAdmin),
		).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("您没有权限添加群组成员")
		}
		return fmt.Errorf("查询操作者权限失败: %w", err)
	}

	// 检查用户是否存在
	_, err = client.User().User.
		Query().
		Where(user.ID(int64(userID))).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("用户不存在")
		}
		return fmt.Errorf("查询用户失败: %w", err)
	}

	// 检查用户是否已经是群组成员
	exists, err := client.ConversationMember().ConversationMember.
		Query().
		Where(
			conversationmember.ConversationID(int64(groupID)),
			conversationmember.UserID(int64(userID)),
		).
		Exist(ctx)

	if err != nil {
		tx.Rollback()
		return fmt.Errorf("检查用户是否已是成员失败: %w", err)
	}

	if exists {
		tx.Rollback()
		return errors.New("用户已经是群组成员")
	}

	// 设置默认角色
	if role == "" {
		role = conversationmember.RoleMember.String()
	}

	// 检查操作者是否有权限设置该角色
	if role == conversationmember.RoleOwner.String() {
		tx.Rollback()
		return errors.New("不能将用户设置为群主")
	}

	if role == conversationmember.RoleAdmin.String() && operatorMember.Role != conversationmember.RoleOwner {
		tx.Rollback()
		return errors.New("只有群主可以设置管理员")
	}

	// 添加用户为群组成员
	_, err = client.ConversationMember().ConversationMember.
		Create().
		SetConversationID(int64(groupID)).
		SetUserID(int64(userID)).
		SetRole(conversationmember.Role(role)).
		Save(ctx)

	if err != nil {
		tx.Rollback()
		return fmt.Errorf("添加群组成员失败: %w", err)
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		return fmt.Errorf("提交事务失败: %w", err)
	}

	return nil
}

// RemoveGroupMember 移除群组成员
func RemoveGroupMember(ctx context.Context, groupID, operatorID, userID uint) error {
	client := db.GetDBClient()

	// 开始事务
	tx, err := client.Group().Tx(ctx)
	if err != nil {
		return fmt.Errorf("开始事务失败: %w", err)
	}
	defer func() {
		if v := recover(); v != nil {
			tx.Rollback()
			panic(v)
		}
	}()

	// 检查会话是否存在且是群聊
	_, err = client.Conversation().Conversation.
		Query().
		Where(
			conversation.ID(int64(groupID)),
			conversation.TypeEQ(conversation.TypeGroup),
		).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("群组不存在")
		}
		return fmt.Errorf("查询群组失败: %w", err)
	}

	// 获取要移除的成员信息
	memberToRemove, err := client.ConversationMember().ConversationMember.
		Query().
		Where(
			conversationmember.ConversationID(int64(groupID)),
			conversationmember.UserID(int64(userID)),
		).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("用户不是群组成员")
		}
		return fmt.Errorf("查询成员失败: %w", err)
	}

	// 不能移除群主
	if memberToRemove.Role == conversationmember.RoleOwner {
		tx.Rollback()
		return errors.New("不能移除群主")
	}

	// 检查操作者权限
	// 1. 自己可以退出群组
	// 2. 群主可以移除任何人
	// 3. 管理员可以移除普通成员
	if operatorID != userID {
		operatorMember, err := client.ConversationMember().ConversationMember.
			Query().
			Where(
				conversationmember.ConversationID(int64(groupID)),
				conversationmember.UserID(int64(operatorID)),
			).
			Only(ctx)

		if err != nil {
			tx.Rollback()
			if ent.IsNotFound(err) {
				return errors.New("您不是群组成员")
			}
			return fmt.Errorf("查询操作者权限失败: %w", err)
		}

		if operatorMember.Role == conversationmember.RoleMember {
			tx.Rollback()
			return errors.New("您没有权限移除其他成员")
		}

		if operatorMember.Role == conversationmember.RoleAdmin && memberToRemove.Role == conversationmember.RoleAdmin {
			tx.Rollback()
			return errors.New("管理员不能移除其他管理员")
		}
	}

	// 移除成员
	_, err = client.ConversationMember().ConversationMember.
		Delete().
		Where(
			conversationmember.ConversationID(int64(groupID)),
			conversationmember.UserID(int64(userID)),
		).
		Exec(ctx)

	if err != nil {
		tx.Rollback()
		return fmt.Errorf("移除成员失败: %w", err)
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		return fmt.Errorf("提交事务失败: %w", err)
	}

	return nil
}

// UpdateMemberRole 更新群组成员角色
func UpdateMemberRole(ctx context.Context, groupID, operatorID, userID uint, role string) error {
	client := db.GetDBClient()

	// 开始事务
	tx, err := client.Group().Tx(ctx)
	if err != nil {
		return fmt.Errorf("开始事务失败: %w", err)
	}
	defer func() {
		if v := recover(); v != nil {
			tx.Rollback()
			panic(v)
		}
	}()

	// 检查会话是否存在且是群聊
	_, err = client.Conversation().Conversation.
		Query().
		Where(
			conversation.ID(int64(groupID)),
			conversation.TypeEQ(conversation.TypeGroup),
		).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("群组不存在")
		}
		return fmt.Errorf("查询群组失败: %w", err)
	}

	// 获取操作者信息
	operatorMember, err := client.ConversationMember().ConversationMember.
		Query().
		Where(
			conversationmember.ConversationID(int64(groupID)),
			conversationmember.UserID(int64(operatorID)),
		).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("您不是群组成员")
		}
		return fmt.Errorf("查询操作者权限失败: %w", err)
	}

	// 只有群主可以更改角色
	if operatorMember.Role != conversationmember.RoleOwner {
		tx.Rollback()
		return errors.New("只有群主可以更改成员角色")
	}

	// 获取要更新的成员信息
	_, err = client.ConversationMember().ConversationMember.
		Query().
		Where(
			conversationmember.ConversationID(int64(groupID)),
			conversationmember.UserID(int64(userID)),
		).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("用户不是群组成员")
		}
		return fmt.Errorf("查询成员失败: %w", err)
	}

	// 不能更改自己的角色
	if operatorID == userID {
		tx.Rollback()
		return errors.New("不能更改自己的角色")
	}

	// 如果要设置为群主，需要特殊处理（转让群主）
	if role == conversationmember.RoleOwner.String() {
		// 将当前群主改为管理员
		_, err = client.ConversationMember().ConversationMember.
			Update().
			Where(
				conversationmember.ConversationID(int64(groupID)),
				conversationmember.UserID(int64(operatorID)),
			).
			SetRole(conversationmember.RoleAdmin).
			Save(ctx)

		if err != nil {
			tx.Rollback()
			return fmt.Errorf("转让群主失败: %w", err)
		}
	}

	// 更新成员角色
	_, err = client.ConversationMember().ConversationMember.
		Update().
		Where(
			conversationmember.ConversationID(int64(groupID)),
			conversationmember.UserID(int64(userID)),
		).
		SetRole(conversationmember.Role(role)).
		Save(ctx)

	if err != nil {
		tx.Rollback()
		return fmt.Errorf("更新成员角色失败: %w", err)
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		return fmt.Errorf("提交事务失败: %w", err)
	}

	return nil
}

// // GroupInfo 群组信息结构体
// type GroupInfo struct {
// 	ID          int64        `json:"id"`
// 	Name        string       `json:"name"`
// 	Description string       `json:"description"`
// 	AvatarURL   string       `json:"avatar_url"`
// 	CreatorID   int64        `json:"creator_id"`
// 	CreatedAt   time.Time    `json:"created_at"`
// 	UpdatedAt   time.Time    `json:"updated_at"`
// 	MemberCount int          `json:"member_count"`
// 	Members     []MemberInfo `json:"members,omitempty"`
// }

// CreateGroup 创建群组
func CreateGroup(ctx context.Context, creatorID uint, name, description, avatarURL string, memberIDs []int64) (uint, error) {
	client := db.GetDBClient()

	// 开始事务
	tx, err := client.Group().Tx(ctx)
	if err != nil {
		return 0, fmt.Errorf("开始事务失败: %w", err)
	}
	defer func() {
		if v := recover(); v != nil {
			tx.Rollback()
			panic(v)
		}
	}()

	// 检查创建者是否存在
	_, err = client.User().User.
		Query().
		Where(user.ID(int64(creatorID))).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return 0, errors.New("创建者不存在")
		}
		return 0, fmt.Errorf("查询创建者失败: %w", err)
	}

	// 创建群组会话
	conv, err := client.Conversation().Conversation.
		Create().
		SetType(conversation.TypeGroup).
		SetName(name).
		SetCreatorID(int64(creatorID)).
		SetDescription(description).
		SetAvatarURL(avatarURL).
		Save(ctx)

	if err != nil {
		tx.Rollback()
		return 0, fmt.Errorf("创建群组失败: %w", err)
	}

	// 添加创建者为群主
	_, err = client.ConversationMember().ConversationMember.
		Create().
		SetConversationID(conv.ID).
		SetUserID(int64(creatorID)).
		SetRole(conversationmember.RoleOwner).
		Save(ctx)

	if err != nil {
		tx.Rollback()
		return 0, fmt.Errorf("添加群主失败: %w", err)
	}

	// 添加其他成员
	if len(memberIDs) > 0 {
		// 检查成员是否存在
		users, err := client.User().User.
			Query().
			Where(user.IDIn(memberIDs...)).
			All(ctx)

		if err != nil {
			tx.Rollback()
			return 0, fmt.Errorf("查询成员失败: %w", err)
		}

		// 检查是否所有成员都存在
		if len(users) != len(memberIDs) {
			tx.Rollback()
			return 0, errors.New("部分成员不存在")
		}

		// 批量添加成员
		bulkMembers := make([]*ent.ConversationMemberCreate, len(memberIDs))
		for i, memberID := range memberIDs {
			bulkMembers[i] = client.ConversationMember().ConversationMember.
				Create().
				SetConversationID(conv.ID).
				SetUserID(int64(memberID)).
				SetRole(conversationmember.RoleMember)
		}

		_, err = client.ConversationMember().ConversationMember.CreateBulk(bulkMembers...).Save(ctx)
		if err != nil {
			tx.Rollback()
			return 0, fmt.Errorf("批量添加成员失败: %w", err)
		}
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		return 0, fmt.Errorf("提交事务失败: %w", err)
	}

	return uint(conv.ID), nil
}

// DeleteGroup 删除群组
func DeleteGroup(ctx context.Context, groupID, operatorID uint) error {
	client := db.GetDBClient()

	// 开始事务
	tx, err := client.Group().Tx(ctx)
	if err != nil {
		return fmt.Errorf("开始事务失败: %w", err)
	}
	defer func() {
		if v := recover(); v != nil {
			tx.Rollback()
			panic(v)
		}
	}()

	// 检查群组是否存在
	_, err = client.Conversation().Conversation.
		Query().
		Where(
			conversation.ID(int64(groupID)),
			conversation.TypeEQ(conversation.TypeGroup),
		).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("群组不存在")
		}
		return fmt.Errorf("查询群组失败: %w", err)
	}

	// 检查操作者是否是群主
	isOwner, err := client.ConversationMember().ConversationMember.
		Query().
		Where(
			conversationmember.ConversationID(int64(groupID)),
			conversationmember.UserID(int64(operatorID)),
			conversationmember.RoleEQ(conversationmember.RoleOwner),
		).
		Exist(ctx)

	if err != nil {
		tx.Rollback()
		return fmt.Errorf("检查操作者权限失败: %w", err)
	}

	if !isOwner {
		tx.Rollback()
		return errors.New("只有群主可以删除群组")
	}

	// 删除所有群组成员
	_, err = client.ConversationMember().ConversationMember.
		Delete().
		Where(conversationmember.ConversationID(int64(groupID))).
		Exec(ctx)

	if err != nil {
		tx.Rollback()
		return fmt.Errorf("删除群组成员失败: %w", err)
	}

	// 删除群组会话
	_, err = client.Conversation().Conversation.
		Delete().
		Where(conversation.ID(int64(groupID))).
		Exec(ctx)

	if err != nil {
		tx.Rollback()
		return fmt.Errorf("删除群组失败: %w", err)
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		return fmt.Errorf("提交事务失败: %w", err)
	}

	return nil
}

// UpdateGroup 更新群组信息
func UpdateGroup(ctx context.Context, groupID, operatorID uint, name, description, avatarURL string) error {
	client := db.GetDBClient()

	// 开始事务
	tx, err := client.Group().Tx(ctx)
	if err != nil {
		return fmt.Errorf("开始事务失败: %w", err)
	}
	defer func() {
		if v := recover(); v != nil {
			tx.Rollback()
			panic(v)
		}
	}()

	// 检查群组是否存在
	conv, err := client.Conversation().Conversation.
		Query().
		Where(
			conversation.ID(int64(groupID)),
			conversation.TypeEQ(conversation.TypeGroup),
		).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("群组不存在")
		}
		return fmt.Errorf("查询群组失败: %w", err)
	}

	// 检查操作者是否有权限（群主或管理员）
	_, err = client.ConversationMember().ConversationMember.
		Query().
		Where(
			conversationmember.ConversationID(int64(groupID)),
			conversationmember.UserID(int64(operatorID)),
			conversationmember.RoleIn(conversationmember.RoleOwner, conversationmember.RoleAdmin),
		).
		Only(ctx)

	if err != nil {
		tx.Rollback()
		if ent.IsNotFound(err) {
			return errors.New("您没有权限更新群组信息")
		}
		return fmt.Errorf("检查操作者权限失败: %w", err)
	}

	// 构建更新
	update := client.Conversation().Conversation.UpdateOne(conv)

	// 只更新提供的字段
	if name != "" {
		update = update.SetName(name)
	}
	if description != "" {
		update = update.SetDescription(description)
	}
	if avatarURL != "" {
		update = update.SetAvatarURL(avatarURL)
	}

	// 执行更新
	_, err = update.Save(ctx)
	if err != nil {
		tx.Rollback()
		return fmt.Errorf("更新群组信息失败: %w", err)
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		return fmt.Errorf("提交事务失败: %w", err)
	}

	return nil
}

// GroupInfo 表示群组信息
type GroupInfo struct {
	ID            int64     `json:"id"`                        // 群组ID
	Name          string    `json:"name"`                      // 群组名称
	Description   string    `json:"description"`               // 群组描述
	AvatarURL     string    `json:"avatar_url"`                // 群组头像
	CreatorID     int64     `json:"creator_id"`                // 创建者ID
	LastMessageAt string    `json:"last_message_at,omitempty"` // 最后消息时间
	CreatedAt     time.Time `json:"created_at"`                // 创建时间
	UpdatedAt     time.Time `json:"updated_at"`                // 更新时间
}

// ListGroups 获取群组列表
func ListGroups(ctx context.Context, userID uint) ([]*GroupInfo, error) {
	client := db.GetDBClient()

	// 获取当前用户参与的群组
	members, err := client.ConversationMember().ConversationMember.
		Query().
		Where(conversationmember.UserID(int64(userID))).
		WithConversation(func(q *ent.ConversationQuery) {
			// 只获取类型为group的会话
			q.Where(conversation.TypeEQ(conversation.TypeGroup))
		}).
		All(ctx)

	if err != nil {
		return nil, fmt.Errorf("查询群组失败: %w", err)
	}

	result := make([]*GroupInfo, 0, len(members))

	for _, member := range members {
		// 检查会话是否存在
		conv := member.Edges.Conversation
		if conv == nil {
			continue
		}

		// 格式化最后消息时间

		groupInfo := &GroupInfo{
			ID:          conv.ID,
			Name:        conv.Name,
			Description: conv.Description,
			AvatarURL:   conv.AvatarURL,
			CreatorID:   conv.CreatorID,
			CreatedAt:   conv.CreatedAt,
			UpdatedAt:   conv.UpdatedAt,
		}

		result = append(result, groupInfo)
	}

	return result, nil
}

// PrivateChatInfo 表示单聊信息
type PrivateChatInfo struct {
	ID            int64     `json:"id"`                        // 会话ID
	PeerUserID    int64     `json:"peer_user_id"`              // 对方用户ID
	PeerUsername  string    `json:"peer_username"`             // 对方用户名
	PeerAvatarURL string    `json:"peer_avatar_url,omitempty"` // 对方头像
	LastMessageAt string    `json:"last_message_at,omitempty"` // 最后消息时间
	CreatedAt     time.Time `json:"created_at"`                // 创建时间
	UpdatedAt     time.Time `json:"updated_at"`                // 更新时间
}

// ListPrivateChats 获取用户的单聊列表
func ListPrivateChats(ctx context.Context, userID uint) ([]*PrivateChatInfo, error) {
	client := db.GetDBClient()

	// 查询当前用户参与的所有单聊会话
	members, err := client.ConversationMember().ConversationMember.
		Query().
		Where(conversationmember.UserID(int64(userID))).
		WithConversation(func(q *ent.ConversationQuery) {
			// 只获取类型为private的会话
			q.Where(conversation.TypeEQ(conversation.TypePrivate))
		}).
		All(ctx)

	if err != nil {
		return nil, fmt.Errorf("查询单聊会话失败: %w", err)
	}

	result := make([]*PrivateChatInfo, 0, len(members))

	for _, member := range members {
		conv := member.Edges.Conversation
		if conv == nil {
			continue
		}

		// 对于每个私聊，查询对方用户信息
		otherMember, err := client.ConversationMember().ConversationMember.
			Query().
			Where(
				conversationmember.ConversationID(conv.ID),
				conversationmember.UserIDNEQ(int64(userID)), // 不等于当前用户
			).
			WithUser().
			Only(ctx)

		if err != nil {
			// 记录错误但继续处理其他会话
			fmt.Printf("获取会话 %d 的对方用户失败: %v\n", conv.ID, err)
			continue
		}

		if otherMember.Edges.User == nil {
			continue
		}

		peerUser := otherMember.Edges.User

		privateChatInfo := &PrivateChatInfo{
			ID:            conv.ID,
			PeerUserID:    peerUser.ID,
			PeerUsername:  peerUser.DisplayName, // 使用显示名称
			PeerAvatarURL: peerUser.AvatarURL,
			LastMessageAt: conv.LastMessageAt.Format(time.RFC3339),
			CreatedAt:     conv.CreatedAt,
			UpdatedAt:     conv.UpdatedAt,
		}

		result = append(result, privateChatInfo)
	}

	return result, nil
}

// CreatePrivateChat 创建单聊会话
func CreatePrivateChat(ctx context.Context, userID, peerUserID uint) (*PrivateChatInfo, error) {
	client := db.GetDBClient()

	// 首先检查是否已存在这两个用户之间的单聊
	exists, err := checkExistingPrivateChat(ctx, userID, peerUserID)
	if err != nil {
		return nil, err
	}

	if exists != nil {
		// 已存在单聊，直接返回
		return exists, nil
	}

	// 开启事务
	tx, err := client.Group().Tx(ctx)
	if err != nil {
		return nil, fmt.Errorf("开启事务失败: %w", err)
	}
	defer func() {
		if v := recover(); v != nil {
			tx.Rollback()
			panic(v)
		}
	}()

	// 获取对方用户信息
	peerUser, err := client.User().User.Get(ctx, int64(peerUserID))
	if err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("获取对方用户信息失败: %w", err)
	}

	// 创建会话
	conv, err := client.Conversation().Conversation.
		Create().
		SetType(conversation.TypePrivate).
		SetName(""). // 单聊没有名称
		SetCreatorID(int64(userID)).
		SetDescription("").
		Save(ctx)

	if err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("创建会话失败: %w", err)
	}

	// 添加当前用户为会话成员
	_, err = client.ConversationMember().ConversationMember.
		Create().
		SetConversationID(conv.ID).
		SetUserID(int64(userID)).
		SetRole(conversationmember.RoleOwner).
		Save(ctx)

	if err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("添加当前用户为会话成员失败: %w", err)
	}

	// 添加对方用户为会话成员
	_, err = client.ConversationMember().ConversationMember.
		Create().
		SetConversationID(conv.ID).
		SetUserID(int64(peerUserID)).
		SetRole(conversationmember.RoleMember).
		Save(ctx)

	if err != nil {
		tx.Rollback()
		return nil, fmt.Errorf("添加对方用户为会话成员失败: %w", err)
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		return nil, fmt.Errorf("提交事务失败: %w", err)
	}

	// 返回创建的单聊信息
	return &PrivateChatInfo{
		ID:            conv.ID,
		PeerUserID:    peerUser.ID,
		PeerUsername:  peerUser.DisplayName,
		PeerAvatarURL: peerUser.AvatarURL,
		CreatedAt:     conv.CreatedAt,
		UpdatedAt:     conv.UpdatedAt,
	}, nil
}

// checkExistingPrivateChat 检查两个用户间是否已有单聊
func checkExistingPrivateChat(ctx context.Context, userID, peerUserID uint) (*PrivateChatInfo, error) {
	client := db.GetDBClient()
	// 查询当前用户所有的单聊会话
	userConversations, err := client.Conversation().Conversation.
		Query().
		Where(conversation.TypeEQ(conversation.TypePrivate)).
		WithMembers(func(q *ent.ConversationMemberQuery) {
			q.Where(conversationmember.UserID(int64(userID)))
		}).
		All(ctx)

	if err != nil {
		return nil, fmt.Errorf("查询用户单聊会话失败: %w", err)
	}

	// 检查每个会话是否包含对方用户
	for _, conv := range userConversations {
		// 检查此会话是否包含对方用户
		count, err := client.ConversationMember().ConversationMember.
			Query().
			Where(
				conversationmember.ConversationID(conv.ID),
				conversationmember.UserID(int64(peerUserID)),
			).
			Count(ctx)

		if err != nil {
			return nil, fmt.Errorf("检查会话成员失败: %w", err)
		}

		if count > 0 {
			// 找到了包含这两个用户的单聊
			peerUser, err := client.User().User.Get(ctx, int64(peerUserID))
			if err != nil {
				return nil, fmt.Errorf("获取对方用户信息失败: %w", err)
			}

			return &PrivateChatInfo{
				ID:            conv.ID,
				PeerUserID:    peerUser.ID,
				PeerUsername:  peerUser.DisplayName,
				PeerAvatarURL: peerUser.AvatarURL,
				LastMessageAt: conv.LastMessageAt.Format(time.RFC3339),
				CreatedAt:     conv.CreatedAt,
				UpdatedAt:     conv.UpdatedAt,
			}, nil
		}
	}

	// 没有找到现有的单聊
	return nil, nil
}

// GetGroup 获取群组信息
func GetGroup(ctx context.Context, groupID, userID uint) (*GroupInfo, error) {
	client := db.GetDBClient()

	// 检查群组是否存在
	conv, err := client.Conversation().Conversation.
		Query().
		Where(
			conversation.ID(int64(groupID)),
			conversation.TypeEQ(conversation.TypeGroup),
		).
		Only(ctx)

	if err != nil {
		if ent.IsNotFound(err) {
			return nil, errors.New("群组不存在")
		}
		return nil, fmt.Errorf("查询群组失败: %w", err)
	}

	// 检查用户是否是群组成员
	isMember, err := client.ConversationMember().ConversationMember.
		Query().
		Where(
			conversationmember.ConversationID(int64(groupID)),
			conversationmember.UserID(int64(userID)),
		).
		Exist(ctx)

	if err != nil {
		return nil, fmt.Errorf("检查用户是否是群组成员失败: %w", err)
	}

	if !isMember {
		return nil, errors.New("您不是该群组的成员")
	}

	// 获取群组成员数量
	// memberCount, err := client.ConversationMember().ConversationMember.
	// Query().
	// Where(conversationmember.ConversationID(int64(groupID))).
	// Count(ctx)

	// 获取群组成员信息
	// members, err := GetGroupMembers(ctx, int64(groupID))
	// if err != nil {
	// 	return nil, fmt.Errorf("获取群组成员信息失败: %w", err)
	// }

	// 构建返回结果
	groupInfo := &GroupInfo{
		ID:          conv.ID,
		Name:        conv.Name,
		Description: conv.Description,
		AvatarURL:   conv.AvatarURL,
		CreatorID:   conv.CreatorID,
		CreatedAt:   conv.CreatedAt,
		UpdatedAt:   conv.UpdatedAt,
	}

	return groupInfo, nil
}
